CV Gap Analyser — Semantic Job Matching with HuggingFace and Pinecone
A CV gap analysis system built to solve a real problem: preparing a job application and needing a systematic way to identify what to evidence. Compares CV and job description using cosine similarity between all-MiniLM-L6-v2 embeddings — capturing semantic alignment beyond shared keywords. A CV describing "deploying models to production cloud infrastructure" matches a role requiring "MLOps and cloud-native deployment" even when the exact words differ.
A curated technology keyword list (~150 terms) identifies specific missing skills. ROUGE metrics flag keyword gaps relevant to ATS screening — a CV can score high semantically but fail automated screening if it uses different terminology. The combination gives a complete picture: conceptual alignment and keyword alignment.
A built-in library of five realistic job descriptions is stored in Pinecone. Every CV analysis retrieves the most semantically similar roles, ranked by score. New job descriptions can be added via POST /api/add-job-url — fetching and indexing directly from a career page URL using trafilatura.
Quick Facts
Overview
Problem
Automating the manual process of comparing a CV against a job description to identify specific skill gaps and produce actionable recommendations — using semantic understanding rather than keyword counting, and accepting job descriptions from text, PDF, or URL including LinkedIn.
Solution
HuggingFace all-MiniLM-L6-v2 for semantic embeddings, a curated keyword list (~150 terms) for skill extraction, rouge-score for ATS keyword overlap, LinkedIn guest API + trafilatura for URL extraction with BeautifulSoup fallback, Pinecone for the job library. FastAPI serves ten match routes covering all CV/JD input combinations. Deployed as a Docker Space on HuggingFace Spaces.
Challenges
Skill extraction is keyword-only. An initial spaCy noun phrase implementation was removed after testing — it consistently extracted job description boilerplate, company names, benefit descriptions, and non-English phrases as false-positive skills. The current keyword list (~150 terms) is precise but cannot catch tools not on the list.
LinkedIn URL extraction is fragile. The unauthenticated guest API endpoint works for direct job posting URLs but is undocumented, may break without notice, and returns varying HTML structure. The login wall blocks standard scrapers entirely on collection and search pages.
Non-English job descriptions break skill extraction. The keyword list is English-only, so Spanish, French, or other-language JDs return few matched skills even when the underlying technologies are the same.
HuggingFace Spaces free tier sleeps after inactivity, causing a cold start delay on the first request. The shared CPU tier can be slow under concurrent load.
Semantic similarity scores are not calibrated against real hiring outcomes. A score of 72/100 does not mean a 72% chance of interview. The thresholds reflect linguistic similarity, not actual job fit.
Results / Metrics
Tested against the Data Science / MLOps Engineer target role. Xavier's CV scores Strong match (76/100) with Good skill coverage. Matched skills include Amazon Bedrock, Amazon SageMaker, AWS, Azure, CI/CD, Docker, FastAPI, GitHub Actions, LangChain, MLflow, MLOps, Pinecone, Python, RAG, and sentence-transformers. Missing skills flagged by the keyword analyser: Bedrock Guardrails, BigQuery, GCP, and Kubernetes — all consistent with the actual gap between the CV and the target role at the time of analysis.
Screenshots
Click to enlarge.
Click to enlarge.